package com.ly.heart.service.king;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.heart.domain.*;
import com.ly.heart.domain.king.BaseChildBo;
import com.ly.heart.domain.king.check.CheckFEntityBo;
import com.ly.heart.domain.king.check.FPolicyDetailBo;
import com.ly.heart.domain.king.check.KingCheckBo;
import com.ly.heart.domain.king.order.FBillTypeIDBo;
import com.ly.heart.domain.king.order.OrderAuditBo;
import com.ly.heart.domain.king.order.OrderSubmitBo;
import com.ly.heart.domain.request.KingBaseSingleRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.service.IKingCheckService;
import com.ly.heart.service.IKingOrgService;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.heart.util.KingCommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * 检验单推送Service
 */
@Component
@Slf4j
public class KingCheckPushService {

    private final SimpleDateFormat dateFormat = new SimpleDateFormat ( "yyyy-MM-dd" );

    @Resource
    private IKingCheckService checkService;
    @Resource
    private IKingOrgService iKingOrgService;

    /**
     * 公用金蝶推送方法
     * 合并保存，提交，审核三步
     * @param kingCheckId
     */
    @Transactional( rollbackFor = Exception.class )
    public void push(String kingCheckId){
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity>().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity::getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        KingCheckEntity kingCheck = checkService.selectKingCheckEntityById(kingCheckId);
        if(Objects.isNull(kingCheck)){
            throw new CustomException("检验单不存在！");
        }
        if(kingCheck.getIsSend() == KingConstUtil.KING_DATA_IS_SEND_YES){
            throw new CustomException("该单据已推送金蝶,无需重复推送！");
        }
        try {
            K3CloudApi client = new K3CloudApi (identifyInfo);
            save(kingCheck,client);
            submit(kingCheck.getDocCode(),client);
            audit(kingCheck.getDocCode(),client);
            updateSendSuccess(kingCheck.getId());
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomException("推送检验单失败！");
        }
    }

    /**
     * 修改推送状态
     * @param kingCheckId
     * @return
     */
    private void updateSendSuccess(String kingCheckId){
        KingCheckEntity kingCheck = new KingCheckEntity();
        kingCheck.setId(kingCheckId);
        kingCheck.setIsSend(KingConstUtil.KING_DATA_IS_SEND_YES);
        kingCheck.setUpdateTime(DateUtils.getNowDate());
        kingCheck.setUpdateName(SecurityUtils.getLoginUser().getUser().getUserId());
        boolean flag = checkService.updateById(kingCheck);
        if(!flag){
            throw new CustomException("修改推送状态失败！");
        }
    }


    /**
     * 金蝶-检验单保存
     * @param kingCheck
     * @param client
     */
    public void save(KingCheckEntity kingCheck, K3CloudApi client){
        try{
            String formId = KingConstUtil.QM_INSPECTBILL;
            KingBaseSingleRequest singleRequest = new KingBaseSingleRequest ();
            KingCheckBo checkBo = this.assembleKingCheck(kingCheck);
            singleRequest.setModel(checkBo);
            //调用接口
            String resultJson = client.save(formId, JSONObject.toJSONString(singleRequest));
            //用于记录结果
            Gson gson = new Gson();
            //对返回结果进行解析和校验
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
            KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
            if (baseResponse.getIsSuccess()) {
                log.info("检验单推送成功: {}", gson.toJson(repoRet.getResult()));
                List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
                if(!CollectionUtils.isEmpty(successEntities)){
                    String docCode = successEntities.get(0).getNumber();
                    //修改为已推送状态
                    checkService.update(new LambdaUpdateWrapper<KingCheckEntity>().set(KingCheckEntity::getIsSend,KingConstUtil.KING_DATA_IS_SEND_YES).eq(KingCheckEntity::getDocCode,docCode));
                }
            } else {
                log.error("检验单推送失败: " + gson.toJson(repoRet.getResult().getResponseStatus()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 金蝶-检验单提交
     * @param docCode
     * @param client
     */
    public void submit(String docCode, K3CloudApi client){
        try{
            OrderSubmitBo submitBo = new OrderSubmitBo();
            List<String> numbers = new ArrayList<>();
            numbers.add(docCode);
            submitBo.setNumbers(numbers);
            String formId = KingConstUtil.QM_INSPECTBILL;
            String resultJson = client.submit(formId, JSON.toJSONString ( submitBo ));
            Gson gson = new Gson();
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
            KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
            if (baseResponse.getIsSuccess()) {
                log.info("检验单提交成功: {}", gson.toJson(repoRet.getResult()));
            } else {
                log.error("检验单提交失败: {}",gson.toJson(repoRet.getResult().getResponseStatus()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 金蝶审核方法
     * @param docCode
     * @param client
     */
    public void audit(String docCode,K3CloudApi client){
        try{
            OrderAuditBo auditBo = new OrderAuditBo();
            List<String> numbers = new ArrayList<>();
            numbers.add(docCode);
            auditBo.setNumbers(numbers);
            String formId = KingConstUtil.QM_INSPECTBILL;
            String resultJson = client.audit(formId,JSON.toJSONString ( auditBo ));
            Gson gson = new Gson();
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
            KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
            if (baseResponse.getIsSuccess()) {
                log.info("检验单审核成功:{}", gson.toJson(repoRet.getResult()));
            } else {
                log.error("检验单审核失败:{}",gson.toJson(repoRet.getResult().getResponseStatus()) );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 组装检验单推送金蝶对象
     * @param kingCheck
     * @return
     */
    private KingCheckBo assembleKingCheck(KingCheckEntity kingCheck){
        KingCheckBo checkBo = new KingCheckBo();
        //单据类型
        FBillTypeIDBo FBillTypeID = new FBillTypeIDBo().setFNUMBER(kingCheck.getDocType());
        checkBo.setFBillTypeID(FBillTypeID);
        //业务类型
        checkBo.setFBusinessType(kingCheck.getDocBusinessType());
        //单据日期
        checkBo.setFDate(dateFormat.format(kingCheck.getDocTime()));
        //来源组织
        BaseChildBo FSourceOrgId = new BaseChildBo().setFNumber(KingConstUtil.DEFAULT_ORG);
        checkBo.setFSourceOrgId(FSourceOrgId);
        //质检组织
        BaseChildBo FInspectOrgId = new BaseChildBo().setFNumber(KingConstUtil.DEFAULT_ORG);
        checkBo.setFInspectOrgId(FInspectOrgId);
        //检验部门
        BaseChildBo FInspectDepId = new BaseChildBo().setFNumber(kingCheck.getCheckDept());
        checkBo.setFInspectDepId(FInspectDepId);
        //质检组
        BaseChildBo FInspectGroupId = new BaseChildBo().setFNumber(kingCheck.getCheckGroup());
        checkBo.setFInspectGroupId(FInspectGroupId);
        //质检员
        FBillTypeIDBo FInspectorId = new FBillTypeIDBo().setFNUMBER(kingCheck.getCheckBy());
        checkBo.setFInspectorId(FInspectorId);
        //描述
        checkBo.setFDescription(kingCheck.getCheckDesc());

        /***检验物料明细***/
        List<CheckFEntityBo> FEntity = new ArrayList<>();
        List<KingCheckMaterialEntity> materialLists = kingCheck.getMaterialLists();
        materialLists.stream().filter(Objects::nonNull).forEach(checkMaterial ->{
            CheckFEntityBo checkFEntityBo = new CheckFEntityBo();
            //物料编码
            FBillTypeIDBo FMaterialId = new FBillTypeIDBo().setFNUMBER(checkMaterial.getMaterialCode());
            checkFEntityBo.setFMaterialId(FMaterialId);
            //质检方案
            FBillTypeIDBo FQCSchemeId = new FBillTypeIDBo().setFNUMBER(checkMaterial.getQualityPlan());
            checkFEntityBo.setFQCSchemeId(FQCSchemeId);
            //单位
            BaseChildBo FUnitID = new BaseChildBo().setFNumber(checkMaterial.getUnit());
            checkFEntityBo.setFUnitID(FUnitID);
            //检验数量
            checkFEntityBo.setFInspectQty(checkMaterial.getCheckNum());
            //合格数
            checkFEntityBo.setFQualifiedQty(checkMaterial.getQualifiedNum());
            //不合格数
            checkFEntityBo.setFUnqualifiedQty(checkMaterial.getUnqualifiedNum());
            //检验结果
            checkFEntityBo.setFInspectResult(checkMaterial.getCheckResult());
            //质检状态
            checkFEntityBo.setFQCStatus(checkMaterial.getCheckStatus());
            //供应商
            FBillTypeIDBo FSupplierId = new FBillTypeIDBo().setFNUMBER(checkMaterial.getSupplierCode());
            checkFEntityBo.setFSupplierId(FSupplierId);
            //仓库
            BaseChildBo FStockId = new BaseChildBo().setFNumber(checkMaterial.getWarehouseCode());
            checkFEntityBo.setFStockId(FStockId);
            //批号
            BaseChildBo FLot = new BaseChildBo().setFNumber(checkMaterial.getBatchNum());
            checkFEntityBo.setFLot(FLot);

            /***物料明细***/
            KingCheckMaterialDetailEntity materialDetail = checkMaterial.getMaterialDetail();
            if(Objects.nonNull(materialDetail)){
                //样本破坏数量
                checkFEntityBo.setFSampleDamageQty(materialDetail.getSampleDestructionNum());
                //样本破坏承担方
                checkFEntityBo.setFSampleDamageBearer(materialDetail.getSampleDestructionUndertake());
            }
            /***检验决策信息***/
            List<FPolicyDetailBo> FPolicyDetail = new ArrayList<>();
            List<KingCheckMaterialUseDecisionEntity> decisionList = checkMaterial.getDecisionList();
            decisionList.stream().filter(Objects::nonNull).forEach(checkDecision -> {
                FPolicyDetailBo fPolicyDetailBo = new FPolicyDetailBo();
                //物料
                FBillTypeIDBo FPolicyMaterialId = new FBillTypeIDBo().setFNUMBER(checkMaterial.getMaterialCode());
                fPolicyDetailBo.setFPolicyMaterialId(FPolicyMaterialId);
                //状态
                fPolicyDetailBo.setFPolicyStatus(checkDecision.getStatus());
                //数量
                fPolicyDetailBo.setFPolicyQty(Integer.parseInt(checkDecision.getNum()));
                //使用决策
                fPolicyDetailBo.setFUsePolicy(checkDecision.getUseDecision());
                //不良处理
                fPolicyDetailBo.setFIsDefectProcess(checkDecision.getIsBadHandle());
                //mrb
                fPolicyDetailBo.setFIsMRBReview(checkDecision.getIsMrb());
                //mrb评审状态
                fPolicyDetailBo.setFMRBReviewStatus(checkDecision.getMrbStatus());
                FPolicyDetail.add(fPolicyDetailBo);
            });
            checkFEntityBo.setFPolicyDetail(FPolicyDetail);
            FEntity.add(checkFEntityBo);
        });
        checkBo.setFEntity(FEntity);
        return checkBo;
    }







}
